package com.backend.modules.system.service.impl;

import com.backend.common.enums.DeptType;
import com.backend.common.exception.BusinessException;
import com.backend.modules.system.dto.DepartmentDTO;
import com.backend.modules.system.dto.DepartmentQueryDTO;
import com.backend.modules.system.entity.SysDepartment;
import com.backend.modules.system.repository.SysDepartmentRepository;
import com.backend.modules.system.service.SysDepartmentService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class SysDepartmentServiceImpl implements SysDepartmentService {

    private final SysDepartmentRepository departmentRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(DepartmentDTO dto) {
        // 校验部门类型
        DeptType deptType = DeptType.valueOf(dto.getType());
        if (deptType == null) {
            throw new BusinessException("无效的部门类型");
        }
        SysDepartment parent =null;
        // 校验上级部门
        if (dto.getParentId() != null) {
             parent = departmentRepository.findById(dto.getParentId())
                    .orElseThrow(() -> new BusinessException("上级部门不存在"));
            
            // 校验部门层级关系
            if (parent.getType() >= dto.getType()) {
                throw new BusinessException("上级部门类型错误");
            }
        } else if (!DeptType.COLLEGE.equals(deptType)) {
            throw new BusinessException("非学院必须指定上级部门");
        }
        
        // 校验同级部门名称是否重复
        if (departmentRepository.existsByNameAndParentId(dto.getName(), dto.getParentId())) {
            throw new BusinessException("同级部门名称已存在");
        }
        
        SysDepartment department = new SysDepartment();
        department.setName(dto.getName());
        department.setParent( parent);
        department.setType(dto.getType());
        department.setSort(dto.getSort());
        
        departmentRepository.save(department);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Long id, DepartmentDTO dto) {
        SysDepartment department = departmentRepository.findById(id)
                .orElseThrow(() -> new BusinessException("部门不存在"));
        
        // 不允许修改部门类型
        if (!department.getType().equals(dto.getType())) {
            throw new BusinessException("不允许修改部门类型");
        }
        
        // 校验同级部门名称是否重复
        if (!department.getName().equals(dto.getName()) && 
                departmentRepository.existsByNameAndParentId(dto.getName(), dto.getParentId())) {
            throw new BusinessException("同级部门名称已存在");
        }
        
        department.setName(dto.getName());
        department.setSort(dto.getSort());
        
        departmentRepository.save(department);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        SysDepartment department = departmentRepository.findById(id)
                .orElseThrow(() -> new BusinessException("部门不存在"));
        
        // 检查是否存在子部门
        List<SysDepartment> children = departmentRepository.findByParentIdOrderBySort(id);
        if (!children.isEmpty()) {
            throw new BusinessException("请先删除子部门");
        }
        
        departmentRepository.delete(department);
    }

    @Override
    public SysDepartment getById(Long id) {
        return departmentRepository.findById(id)
                .orElseThrow(() -> new BusinessException("部门不存在"));
    }

    @Override
    public List<SysDepartment> getTree() {
        // 获取所有根节点（学院）
        List<SysDepartment> roots = departmentRepository.findRoots();
        
        // 递归构建树
        return roots.stream()
                .peek(this::buildTree)
                .collect(Collectors.toList());
    }
    
    private void buildTree(SysDepartment parent) {
        List<SysDepartment> children = departmentRepository.findByParentIdOrderBySort(parent.getId());
        if (!children.isEmpty()) {
            parent.setChildren(children);
            children.forEach(this::buildTree);
        }
    }

    @Override
    public List<SysDepartment> list(DepartmentQueryDTO query) {
        // 这里可以使用JPA Specification来实现动态查询
        // 为了简单起见，我们先使用基础查询
        if (query.getParentId() != null) {
            return departmentRepository.findByParentIdOrderBySort(query.getParentId());
        }
        return departmentRepository.findAll();
    }

    @Override
    public List<SysDepartment> getTree(DepartmentQueryDTO query) {
        // 获取所有根节点（学院）
        List<SysDepartment> roots = departmentRepository.findRoots();
        
        // 递归构建树
        return roots.stream()
                .peek(this::buildTree)
                .collect(Collectors.toList());
    }

    @Override
    public List<SysDepartment> listByIds(Collection<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return new ArrayList<>();
        }
        return departmentRepository.findAllById(ids);
    }
} 